﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;
using System.Web;

#region License
/*
 *  Copyright (c) Dumuzi.cn 2009 , All rights reserved.
 *  CLR Version: 2.0.50727.4927
 *  NameSpace: Summer.Object
 *  Author:Edwin Tai,戴佳顺
 *  Msn:edwin19861218@hotmail.com
 *  QQ: 1961218
 *  Date:2009/10/30 14:57:48
 *  Licensed under the Microsoft Public License (Ms-PL)
 *  This license governs use of the accompanying software. 
 *  If you use the software, you accept this license.
 *  If you do not accept the license, do not use the software.
 */
#endregion

namespace Summer.Object
{
    /// <summary>
    /// Extension collection base class
    /// </summary>
    /// <typeparam name="T1">Extension Collection extend IExtension<T></typeparam>
    /// <typeparam name="T2">Extension Object</typeparam>
    public class ExtensionCollection<T1, T2> : IExtensionCollection<T1> where T1 : IExtensionObject<T2>
    {
        /// <summary>
        /// date collection
        /// </summary>
        private ICollection<T1> m_collection = new Collection<T1>();
        /// <summary>
        /// The T2 handle from Construction
        /// </summary>
        private T2 m_extension=default(T2);

        public ExtensionCollection()
        {

        }
        public ExtensionCollection(T2 t2)
        {
            this.m_extension = t2;
        }

        /// <summary>
        /// Get or set the additional data used by T3 load
        /// </summary>
        public T2 AdditionalData
        {
            get { return this.m_extension; }
            set { this.m_extension = value; }
        }

        #region ICollection<T1> 成员
        /// <summary>
        /// Run IExtension.Attach() method and add itself to the base collection
        /// </summary>
        /// <param name="item"></param>
        public void Add(T1 item)
        {
            if (!m_collection.Contains(item) && item.Load(m_extension))
            {
                this.m_collection.Add(item);
            }
        }

        public void Clear()
        {
            foreach (T1 item in m_collection) 
            {
                item.UnLoad();
                m_collection.Remove(item);
            }
        }

        public bool Contains(T1 item)
        {
            return this.m_collection.Contains(item);
        }

        public void CopyTo(T1[] array, int arrayIndex)
        {
            this.m_collection.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get 
            {
                return this.m_collection.Count; 
            }
        }

        public bool IsReadOnly
        {
            get { return this.m_collection.IsReadOnly; }
        }
        /// <summary>
        /// Find the obj by type
        /// Run IExtension.Detach() and remove it from base collection
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Remove(T1 item)
        {
            foreach (T1 t in this.m_collection) 
            {
                if (t.Equals(item) || t.GetType() == item.GetType())
                {
                    return t.UnLoad() && this.m_collection.Remove(t);
                }
            }
            return false;
        }

        #endregion

        #region IEnumerable<T1> 成员

        public IEnumerator<T1> GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.m_collection.GetEnumerator();
        }

        #endregion
    }
}
